module Chess
    class Player
        def initialize db=nil
            @db = db
        end

        def next_move_from_game(game, suffix)
            game[suffix.size..-1].split.first
        end
        
        def next_move suffix
            if suffix.split.size.even?
                # max for wthite
                order = -1
            else
                order = 1
            end

            next_value = Hash.new(0)             
            @db.games.each do |game|
                next if !game.start_with? suffix
                move = next_move_from_game(game, suffix)
                if game =~ /1-0$/ then
                    next_value[move] += 1
                elsif game =~ /0-1$/ then
                    next_value[move] -= 1
                elsif game =~ /1\/2-1\/2$/ then
                    next_value[move] += 0.5
                end 
            end
            puts next_value

            moves = next_value.sort {|a,b| order  * (a[1] <=> b[1]) }
            moves.first[0]
        end
    end
    
    class DB
        attr_reader :game_counter, :games
        
        def initialize db_file=nil
            @db_file = db_file
            @game_counter = 0
        end

        def get_moves text
            moves = ''
            text.split.each do |move|
                next if move =~ /^[0-9]+\.$/
                moves << ' ' if moves.size > 1
                moves << move.gsub(/^[0-9]+\./, '')
            end
            moves
        end
        
        def add_game game
            @games ||= []
            @games << game
        end
        
        def copy_db_to_memory
            @game_counter = 0
            @games = []
            File.open( @db_file) do |in_file|
                while (line = in_file.gets)
                    next if line.size < 50
                    @games << line
                    @game_counter += 1
                    puts to_s if @game_counter % 100_000 == 0
                end
            end
        end
        
        def report
            w,b,d = 0,0,0;
            first_move = Hash.new(0) 
            @games.each do |game|
                if game =~ /1-0$/ then
                    w += 1
                    first_move[game.split[0]] += 1
                elsif game =~ /0-1$/ then
                    b += 1
                elsif game =~ /1\/2-1\/2$/ then
                    d += 1
                end 
            end
            
            first_move.reject! { |move, count| count < 1000 }
            moves = first_move.sort {|a,b| -(a[1] <=> b[1])}
            
            puts "white: #{w}, black: #{b}, drawn: #{d}, move: #{moves.first[0]}"
        end
        
        def import_from_pgn_file pgn_file
            text = ''
            state = :parsing_tags
            File.open(pgn_file) do |in_file|
                File.open(@db_file, 'a') do |out_file|
                    while (line = in_file.gets)
                        if line.size > 2 then
                            text << line if state == :parsing_moves
                        else
                            if state == :parsing_tags then
                                state = :parsing_moves
                            elsif state == :parsing_moves then
                                state = :parsing_tags
                                out_file.puts get_moves(text)
                                @game_counter += 1
                                text.clear
                            end
                        end
                    end
                end
            end
        end
        
        def include? moves
            found = false
            File.open(@db_file) do |in_file|
                while (line = in_file.gets.chop)
                    break if found = (line == moves)
                end
            end
            found
        end
            
        def to_s
            "Games in #{@db_file}: #{@game_counter}"
        end        
    end
end